package com.adee.java;

import java.util.concurrent.*;

/**
 * ForkJoinPool介绍
 * https://blog.csdn.net/dabaoshiwode/article/details/110103070
 *
 * ForkJoinPool最佳实践
 * （1）最适合的是计算密集型任务
 * （2）在需要阻塞工作线程时，可以使用ManagedBlocker；
 * （3）不应该在RecursiveTask的内部使用ForkJoinPool.invoke()/invokeAll()；
 * 总结
 * （1）ForkJoinPool特别适合于“分而治之”算法的实现；
 * （2）ForkJoinPool和ThreadPoolExecutor是互补的，不是谁替代谁的关系，二者适用的场景不同；
 * （3）ForkJoinTask有两个核心方法——fork()和join()，有三个重要子类——RecursiveAction、RecursiveTask和CountedCompleter；
 * （4）ForkjoinPool内部基于“工作窃取”算法实现；
 * （5）每个线程有自己的工作队列，它是一个双端队列，自己从队列头存取任务，其它线程从尾部窃取任务；
 * （6）ForkJoinPool最适合于计算密集型任务，但也可以使用ManagedBlocker以便用于阻塞型任务；
 * （7）RecursiveTask内部可以少调用一次fork()，利用当前线程处理，这是一种技巧；
 * ===========================================================================
 *
 * 阿里面试题：题目：如何充分利用多核CPU，计算超大数组中所有整数的和？
 * 分治：使用线程池，线程数为cpu核数，切分数组，提交到线程池执行求和，最后在递归拆分。
 *
 *
 *
 */
public class Test022_3_ForkJoinPool {
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        // 计算1亿个整数的和
        int n = 100000000; // 1亿
        int[] arr = new int[n];
        for (int i = 0; i < n; i++) {
            arr[i] = ThreadLocalRandom.current().nextInt();

        }
    }
}
